﻿
'Imports StandAuto.DesktopApi

Public Class AcessoCamadaDeDados
#Region "Veiculos"
    Public Shared Function ExisteVeiculo(id As Integer) As Boolean
        Using contextoBasedeDados As New Database.ContextoStandAuto()
            Return contextoBasedeDados.Veiculos.Any(Function(z) z.veiculoId = id)
        End Using
    End Function
    Public Shared Sub GuardarVeiculo(Veiculo As Veiculo)
        Dim dbVeiculo As Database.Veiculo = New Database.Veiculo()
        Using contextoBasedeDados As New Database.ContextoStandAuto()
            If contextoBasedeDados.Veiculos.Any(Function(z) z.veiculoId = Veiculo.Id) Then
                'se exite é um update
                dbVeiculo = contextoBasedeDados.Veiculos.First(Function(z) z.veiculoId = Veiculo.Id)
            Else
                'vamos adicionar ao contexto 
                contextoBasedeDados.Veiculos.Add(dbVeiculo)
            End If
            With dbVeiculo
                .cilindrada = Veiculo.cilindrada
                .descricao = Veiculo.descricao
                .Marca = Veiculo.Marca
                .modelo = Veiculo.Modelo
                .numProntas = Veiculo.numPortas
                .potencia = Veiculo.potencia
                .preco = Veiculo.valorVenda.ConvertMoedapDecimal(",")
            End With
            'agora que os dados estao mapeados é so guardar.
            contextoBasedeDados.SaveChanges()
        End Using
    End Sub

    Public Shared Function GetAllViaturas() As List(Of Veiculo)
        Using contextoBasedeDados As New Database.ContextoStandAuto
            Dim viaturasRet As List(Of Veiculo) = New List(Of Veiculo)()
            contextoBasedeDados.Veiculos.ToList().ForEach(Function(z)
                                                              viaturasRet.Add(GetViatura(z))
                                                              Return True
                                                          End Function)
            Return viaturasRet
        End Using
    End Function


    Public Shared Function GetViatura(veiculoId As Integer) As Veiculo
        Using contextoBasedeDados As New Database.ContextoStandAuto()
            Return GetViatura(contextoBasedeDados.Veiculos.First(Function(z) z.veiculoId = veiculoId))
        End Using
    End Function
    Public Shared Function GetViatura(veiculo As Database.Veiculo) As Veiculo
        Dim viaturaRet = New Veiculo() With {
       .cilindrada = veiculo.cilindrada,
       .descricao = veiculo.descricao,
       .Id = veiculo.veiculoId,
       .Marca = veiculo.Marca,
       .Modelo = veiculo.modelo,
       .numPortas = veiculo.numProntas,
       .potencia = veiculo.potencia,
       .valorVenda = veiculo.preco.ConvertDecimalMoeda,
       .stock = getStock(veiculo.veiculoId)
        }

        Return viaturaRet
    End Function




#End Region
#Region "Compras"


    Public Shared Function GetAllComprasByVeiculo(veiculoId As Integer) As List(Of Compra)
        Using contextoBasedeDados As New Database.ContextoStandAuto()
            Return GetAllCompras(New Veiculo() With {.Id = veiculoId}, contextoBasedeDados).ToList()
        End Using
    End Function
    Public Shared Function GetAllComprasByFornecedor(fornecedorId As Integer) As List(Of Compra)
        Using contextoBasedeDados As New Database.ContextoStandAuto()
            Return GetAllCompras(New Fornecedor() With {.id = fornecedorId}, contextoBasedeDados).ToList()
        End Using
    End Function
    Public Shared Iterator Function GetAllCompras(Of T)(objPesq As T, contextoBasedeDados As Database.ContextoStandAuto) As IEnumerable(Of Compra)

        Dim valueCompair As Integer =
            objPesq.GetType().GetProperties().First(Function(z) z.Name.EqualsIgnoreCase("id")).
            GetValue(objPesq)
        Dim DinFunc As Expressions.Expression(Of Func(Of Database.Compra, Boolean)) = Function(z As Database.Compra) 1 = 1
        Select Case objPesq.GetType().Name.ToLower()
            Case "veiculo"
                DinFunc = Function(z As Database.Compra) z.veiculoId = valueCompair
            Case "fornecedor"
                DinFunc = Function(z As Database.Compra) z.fornecedorId = valueCompair
        End Select
        For Each dbCompra As Database.Compra In contextoBasedeDados.Compras().Where(DinFunc)
            Yield GetCompra(dbCompra, contextoBasedeDados)
        Next
    End Function
    Public Shared Function GetCompra(compra As Database.Compra, contextoBasedeDados As Database.ContextoStandAuto) As Compra
        Dim compraRet As Compra = New Compra() With {
        .fornecedorId = compra.fornecedorId,
        .data = compra.data.ToString("yyyy-MM-dd"),
        .id = compra.compraId,
        .quantidade = compra.quantidade,
        .valor = compra.valor.ConvertDecimalMoeda,
        .veiculoId = compra.veiculoId
        }
        If (compra.fornecedor IsNot Nothing) Then
            compraRet.fornecedor = getFornecedor(compra.fornecedor)
        Else
            compraRet.fornecedor = getFornecedor(compra.fornecedorId, contextoBasedeDados)
        End If
        Return compraRet
    End Function
    Public Shared Sub RemoveCompra(compra As Compra)
        Using contextoBasedeDados As New Database.ContextoStandAuto()
            contextoBasedeDados.Compras.Remove(contextoBasedeDados.Compras.First(Function(z) z.compraId = compra.id))
            contextoBasedeDados.SaveChanges()
        End Using

    End Sub
    Public Shared Sub guardaCompra(compra As Compra)
        Using contextoBasedeDados As New Database.ContextoStandAuto
            Dim compraToSave = transformaCompraEmClassBD(compra, contextoBasedeDados)
            contextoBasedeDados.Compras.Add(compraToSave)
            contextoBasedeDados.SaveChanges()
        End Using
    End Sub
    Public Shared Function transformaCompraEmClassBD(Compra As Compra, contextoBasedeDados As Database.ContextoStandAuto) As Database.Compra
        Dim CompraRet As New Database.Compra() With {
        .data = Convert.ToDateTime(Compra.data),
        .fornecedorId = Compra.fornecedorId,
        .quantidade = Compra.quantidade,
        .valor = Compra.valor,
        .veiculo = New Database.Veiculo() With {.veiculoId = Compra.veiculoId},
        .veiculoId = Compra.veiculoId
        }
        CompraRet.veiculo = contextoBasedeDados.Veiculos.First(Function(z) z.veiculoId = CompraRet.veiculoId)
        CompraRet.fornecedor = contextoBasedeDados.Fornecedores.First(Function(z) z.fornecedorId = CompraRet.fornecedorId)
        Return CompraRet
    End Function
    Public Shared Iterator Function getAllCompras() As IEnumerable(Of Compra)
        Using contextoBasedeDados As New Database.ContextoStandAuto()
            For Each compra In contextoBasedeDados.Compras
                Yield GetCompra(compra, contextoBasedeDados)
            Next
        End Using
    End Function
#End Region
#Region "fornecedor"
    Public Shared Function GetAllFornecedores() As List(Of Fornecedor)
        Using contextoBasedeDados As New Database.ContextoStandAuto()
            Return contextoBasedeDados.Fornecedores.AsEnumerable().
                Select(Of Fornecedor)(Function(z) getFornecedor(z)).ToList()
        End Using
    End Function
    Public Shared Function getFornecedor(fornecedorId As Integer)

        Using contextoBasedeDados As New Database.ContextoStandAuto()
            Return getFornecedor(fornecedorId, contextoBasedeDados)
        End Using
    End Function
    Public Shared Function getFornecedor(fornecedorId As Integer, contextoBasedeDados As Database.ContextoStandAuto)
        Return getFornecedor(contextoBasedeDados.Fornecedores.First(Function(y) y.fornecedorId = fornecedorId))
    End Function
    Public Shared Function getFornecedor(fornecedor As Database.Fornecedor)
        Return New Fornecedor() With {
            .codigoPostal = fornecedor.codigoPostal,
            .contribuinte = fornecedor.contribuinte,
            .id = fornecedor.fornecedorId,
            .localidade = fornecedor.localidade,
            .morada = fornecedor.morada,
            .nome = fornecedor.nome,
            .telefone = fornecedor.telefone
        }


    End Function
    Public Shared Sub SaveFornecedor(fornecedor As Fornecedor)
        Using contextoBasedeDados As New Database.ContextoStandAuto()
            Dim FornToSave As Database.Fornecedor

            If fornecedor.id > 0 Then
                FornToSave = contextoBasedeDados.Fornecedores.First(Function(z) z.fornecedorId = fornecedor.id)
            Else
                FornToSave = New Database.Fornecedor()
                contextoBasedeDados.Fornecedores.Add(FornToSave)
            End If
            With FornToSave
                .codigoPostal = fornecedor.codigoPostal
                .contribuinte = fornecedor.contribuinte
                .localidade = fornecedor.localidade
                .morada = fornecedor.morada
                .nome = fornecedor.nome
                .telefone = fornecedor.telefone
            End With
            contextoBasedeDados.SaveChanges()
        End Using

    End Sub
#End Region
#Region "Vendas"
    Public Shared Function GetAllVendasByVeiculo(veiculoId As Integer) As List(Of Venda)
        Using contextoBasedeDados As New Database.ContextoStandAuto()
            Return GetAllVendas(New Veiculo() With {.Id = veiculoId}, contextoBasedeDados).ToList()
        End Using
    End Function
    Public Shared Function GetAllVendasByCliente(clienteId As Integer) As List(Of Venda)
        Using contextoBasedeDados As New Database.ContextoStandAuto()
            Return GetAllVendas(New Cliente() With {.id = clienteId}, contextoBasedeDados).ToList()
        End Using
    End Function
    Public Shared Function GetAllVendasByVendedor(vendedorId As Integer) As List(Of Venda)
        Using contextoBasedeDados As New Database.ContextoStandAuto()
            Return GetAllVendas(New Vendedor() With {.id = vendedorId}, contextoBasedeDados).ToList()
        End Using
    End Function
    Public Shared Iterator Function GetAllVendas(Of T)(objPesq As T, contextoBasedeDados As Database.ContextoStandAuto) As IEnumerable(Of Venda)
        Dim valueCompair As Integer =
            objPesq.GetType().GetProperties.First(Function(z) z.Name.EqualsIgnoreCase("id")).
            GetValue(objPesq)
        Dim DinFunc As Expressions.Expression(Of Func(Of Database.Venda, Boolean)) = Function(z) 1 = 1

        Select Case objPesq.GetType().Name.ToLower()
            Case "veiculo"
                DinFunc = Function(z) z.veiculoId = valueCompair
            Case "cliente"
                DinFunc = Function(z) z.clienteId = valueCompair
            Case "vendedor"
                DinFunc = Function(z) z.vendedorId = valueCompair
        End Select

        For Each dbVenda As Database.Venda In contextoBasedeDados.vendas.Where(DinFunc)
            Yield GetVenda(dbVenda, contextoBasedeDados)
        Next
    End Function
    Public Shared Sub RemoveVenda(venda As Venda)
        Using contextoBasedeDados As New Database.ContextoStandAuto()
            contextoBasedeDados.vendas.Remove(contextoBasedeDados.vendas.First(Function(z) z.vendaId = venda.id))
            contextoBasedeDados.SaveChanges()
        End Using

    End Sub
    Public Shared Function GetVenda(venda As Database.Venda, contextoBasedeDados As Database.ContextoStandAuto) As Venda
        Dim vendaRet As Venda = New Venda() With {
        .clienteId = venda.clienteId,
        .data = venda.data.ToString("yyyy-MM-dd"),
        .id = venda.vendaId,
        .quantidade = venda.quantidade,
        .valor = venda.valor.ConvertDecimalMoeda,
        .veiculoId = venda.veiculoId,
        .vendedorId = venda.vendedorId
        }
        If (venda.vendedor IsNot Nothing) Then
            vendaRet.vendedor = getVendedor(venda.vendedor)
        Else
            vendaRet.vendedor = getVendedor(venda.vendedorId, contextoBasedeDados)
        End If
        If (venda.cliente IsNot Nothing) Then
            vendaRet.cliente = getCliente(venda.cliente)
        Else
            vendaRet.cliente = getCliente(venda.clienteId, contextoBasedeDados)
        End If
        Return vendaRet
    End Function
    Public Shared Sub guardaVenda(venda As Venda)
        Using contextoBasedeDados As New Database.ContextoStandAuto
            Dim vendaToSave = transformaVendaEmClassBD(venda, contextoBasedeDados)
            contextoBasedeDados.vendas.Add(vendaToSave)
            contextoBasedeDados.SaveChanges()
        End Using
    End Sub
    Public Shared Function transformaVendaEmClassBD(venda As Venda, contextoBasedeDados As Database.ContextoStandAuto) As Database.Venda
        Dim vendaRet As New Database.Venda() With {
        .data = Convert.ToDateTime(venda.data),
        .quantidade = venda.quantidade,
        .valor = venda.valor,
        .veiculoId = venda.veiculoId,
        .clienteId = venda.clienteId,
        .vendedorId = venda.vendedorId
        }
        vendaRet.veiculo = contextoBasedeDados.Veiculos.First(Function(z) z.veiculoId = vendaRet.veiculoId)
        vendaRet.cliente = contextoBasedeDados.Clientes.First(Function(z) z.clienteid = vendaRet.clienteId)
        vendaRet.vendedor = contextoBasedeDados.vendedores.First(Function(z) z.vendedorId = vendaRet.vendedorId)
        Return vendaRet
    End Function
    Public Shared Iterator Function GetAllVendas() As IEnumerable(Of Venda)

        Using contextoBasedeDados As New Database.ContextoStandAuto()
            For Each venda In contextoBasedeDados.vendas
                Yield GetVenda(venda, contextoBasedeDados)
            Next
        End Using
    End Function
#End Region
#Region "Cliente"
    Public Shared Function getAllClientes() As List(Of Cliente)
        Using contextoBasedeDados As New Database.ContextoStandAuto()
            Return contextoBasedeDados.Clientes().AsEnumerable().
                Select(Function(z) getCliente(z)).ToList()
        End Using
    End Function
    Public Shared Function getCliente(ClienteId As Integer) As Cliente
        Using contextoBasedeDados As New Database.ContextoStandAuto()
            Return getCliente(ClienteId, contextoBasedeDados)
        End Using
    End Function
    Public Shared Function getCliente(ClienteId As Integer, contextoBasedeDados As Database.ContextoStandAuto) As Cliente

        Return getCliente(contextoBasedeDados.Clientes.First(Function(z) z.clienteid = ClienteId))

    End Function
    Public Shared Function getCliente(cliente As Database.Cliente) As Cliente
        Return New Cliente() With {
        .codigoPostal = cliente.codigoPostal,
        .contribuinte = cliente.contribuinte,
        .dataNascimento = cliente.dataNascimento.ToString("yyyy-MM-dd"),
        .id = cliente.clienteid,
        .localidade = cliente.localidade,
        .morada = cliente.morada,
        .nome = cliente.nome,
        .telefone = cliente.telefone
        }

    End Function

    Public Shared Sub SaveCliente(cliente As Cliente)

        Using contextoBasedeDados As New Database.ContextoStandAuto()
            Dim cltToSave As Database.Cliente

            If cliente.id > 0 Then
                cltToSave = contextoBasedeDados.Clientes.First(Function(z) z.clienteid = cliente.id)
            Else
                cltToSave = New Database.Cliente()
                contextoBasedeDados.Clientes.Add(cltToSave)
            End If
            With cltToSave
                .codigoPostal = cliente.codigoPostal
                .contribuinte = cliente.contribuinte
                .dataNascimento = cliente.dataNascimento
                .localidade = cliente.localidade
                .morada = cliente.morada
                .nome = cliente.nome
                .telefone = cliente.telefone
            End With
            contextoBasedeDados.SaveChanges()
        End Using

    End Sub
#End Region
#Region "Vendedor"
    Public Shared Function getAllVendedores() As List(Of Vendedor)
        Using contextoBasedeDados As New Database.ContextoStandAuto()
            Return contextoBasedeDados.vendedores().AsEnumerable().
                Select(Function(z) getVendedor(z)).ToList()
        End Using
    End Function
    Public Shared Function getVendedor(vendedorId As Integer) As Vendedor
        Using contextoBasedeDados As New Database.ContextoStandAuto()
            Return getVendedor(vendedorId, contextoBasedeDados)
        End Using
    End Function
    Public Shared Function getVendedor(vendedorId As Integer, contextoBasedeDados As Database.ContextoStandAuto) As Vendedor
        Return getVendedor(contextoBasedeDados.vendedores.First(Function(z) z.vendedorId = vendedorId))
    End Function
    Public Shared Function getVendedor(vendedor As Database.Vendedor) As Vendedor
        Return New Vendedor() With {
            .codigoPostal = vendedor.codigoPostal,
            .contribuinte = vendedor.contribuinte,
            .id = vendedor.vendedorId,
            .localidade = vendedor.localidade,
            .morada = vendedor.morada,
            .nome = vendedor.nome,
            .telefone = vendedor.telefone
        }
    End Function

    Public Shared Sub SaveVendedor(Vendedor As Vendedor)
        Using contextoBasedeDados As New Database.ContextoStandAuto()
            Dim VendToSave As Database.Vendedor

            If Vendedor.id > 0 Then
                VendToSave = contextoBasedeDados.vendedores.First(Function(z) z.vendedorId = Vendedor.id)
            Else
                VendToSave = New Database.Vendedor()
                contextoBasedeDados.vendedores.Add(VendToSave)
            End If
            With VendToSave
                .codigoPostal = Vendedor.codigoPostal
                .contribuinte = Vendedor.contribuinte
                .localidade = Vendedor.localidade
                .morada = Vendedor.morada
                .nome = Vendedor.nome
                .telefone = Vendedor.telefone
            End With
            contextoBasedeDados.SaveChanges()
        End Using
    End Sub
#End Region

    Private Shared Function getStock(veiculoid As Integer) As Integer
        Dim totalvendas As Integer, totalcompras As Integer

        GetAllVendasByVeiculo(veiculoid).ForEach(Function(z)
                                                     totalvendas = totalvendas + z.quantidade
                                                     Return Nothing
                                                 End Function
                                        )

        GetAllComprasByVeiculo(veiculoid).ForEach(Function(z)
                                                      totalcompras += z.quantidade
                                                      Return Nothing
                                                  End Function
                                            )
        Return totalcompras - totalvendas

    End Function
#Region "Settings"

    Public Shared Sub saveSetting(key As String, value As String)
        Using contextoBasedeDados As New Database.ContextoStandAuto()
            If contextoBasedeDados.Settings.Any(Function(z) z.key.ToLower = key.ToLower) Then
                contextoBasedeDados.Settings.First(Function(z) z.key.ToLower = key.ToLower).Value = value
            Else
                contextoBasedeDados.Settings.Add(New Database.Setting() With {
                                                 .key = key,
                                                 .Value = value}
                                                 )
            End If
            contextoBasedeDados.SaveChanges()
        End Using

    End Sub
    Public Shared Function getSetting(key As String) As String
        Using contextoBasedeDados As New Database.ContextoStandAuto()
            If contextoBasedeDados.Settings.Any(Function(z) z.key.ToLower = key.ToLower) Then
                Return contextoBasedeDados.Settings.First(Function(z) z.key.ToLower = key.ToLower).Value
            End If
        End Using
        Return Nothing
    End Function
#End Region
End Class
